import React, { useContext, memo } from "react";
import ContextProvide, { Context } from "./context";
import { RAction } from "./reducer";

const Show = () => {
  // MARK: 3、通过 useContext 消费数据
  const { state } = useContext(Context)!;
  return <div>当前数字是：{state.count}</div>;
};

const UI: React.FC<{ dispatch: React.Dispatch<RAction> }> = memo((props) => {
  console.log("Increase");
  return <button onClick={() => props.dispatch({ type: "add" })}> + </button>;
});

const Increase = () => {
  const { dispatch } = useContext(Context)!;
  return <UI dispatch={dispatch} />;
};

const Decrease = () => {
  console.log("Decrease");
  const { dispatch } = useContext(Context)!;
  return <button onClick={() => dispatch({ type: "sub" })}> - </button>;
};

const Reset = memo(() => {
  console.log("Reset");
  // ! context API 并不能细粒度地分析某个组件依赖了 context 里的哪个属性，并且它可以穿透 React.memo 和 dependence 的对比
  // ! 比如这里仅使用了 dispatch，但是当 state 有改变时，组件依然会重新渲染，并且无法拦截
  // ! 如果必须要解决的话，可以拆分成两个 context，但当 context 过多又会出现 contextProvider 嵌套地狱问题，如图：react-context1.png
  const { dispatch } = useContext(Context)!;
  const initialValue = 8;
  return (
    <button onClick={() => dispatch({ type: "reset", payload: initialValue })}>
      {" "}
      重置{" "}
    </button>
  );
});

const App = () => {
  return (
    <ContextProvide>
      <Show />
      <Increase />
      <Decrease />
      <Reset />
    </ContextProvide>
  );
};

export default App;
